package org.smile.db.dao.impl;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.sql.DataSource;

import org.smile.beans.BeanUtils;
import org.smile.db.dao.ConfigContext;
import org.smile.db.dao.IBaseDAO;
import org.smile.db.handler.FieldBeanRowHandler;
import org.smile.db.sql.SQLRunner;


public class BaseDAOImpl<E extends BaseVo> implements IBaseDAO<E>
{
	
	protected  DataSource dataSource;
	
	public BaseDAOImpl(DataSource ds){
		this.dataSource=ds;
	}
	public BaseDAOImpl(){
	}
	
	public List<E> queryAll(Class<E> c) throws Exception
	{
		return this.query(c, null);
	}

	public List<E> query(Class<E> c, String whereSql,Object ... params) throws Exception
	{
		StringBuffer sql = new StringBuffer();
		sql.append("select *");

		sql.append(" from ").append(ConfigContext.getInstance().getTableName(c));
		if (!(whereSql == null || "".equals(whereSql.trim())))
		{
			sql.append(" where ").append(whereSql);
		}
		SQLRunner runner=new SQLRunner(dataSource.getConnection(),new FieldBeanRowHandler(c));
		try
		{
			return runner.query(sql.toString(),params);
		} finally
		{
			runner.closeConn();
		}
	}

	/**
	 * 
	 */
	public E queryById(Class<E> c, Object id) throws Exception
	{
		Field idfield = ConfigContext.getInstance().getIdField(c);
		String whereSql = ConfigContext.getInstance().getIdCollmun(idfield) + "= ?";
		if(idfield==null)
		{
			throw new Exception("没有指定主键列");
		}
		List<E> l=this.query(c, whereSql,new Object[]{id});
		if (l.size() > 0)
		{
			return l.get(0);
		} else
		{
			return null;
		}
	}

	public void delete(Class<E> c, String whereSql,Object... params) throws Exception
	{
		StringBuffer sql = new StringBuffer();
		sql.append("delete from ").append(ConfigContext.getInstance().getTableName(c));
		if (!(whereSql == null || "".equals(whereSql.trim())))
		{
			sql.append(" where ").append(whereSql);
		}
		SQLRunner runner=new SQLRunner(dataSource.getConnection());
		try
		{
			runner.execute(sql.toString(),params);
		} finally
		{
			runner.closeConn();
		}
	}

	public void deleteById(Class<E> c, Object id) throws Exception
	{
		Field idfield = ConfigContext.getInstance().getIdField(c);
		String whereSql =ConfigContext.getInstance().getIdCollmun(idfield)+" = ?" ;
		this.delete(c, whereSql,new Object[]{id});
	}

	public void deleteAll(Class<E> c) throws Exception
	{
		this.delete(c, null);
	}


	/**
	 * 
	 */
	public void add(E e) throws Exception
	{
		Map<String,Field> fieldMap = ConfigContext.getInstance().getDataField(e.getClass());
		StringBuffer sql = new StringBuffer();
		sql.append("INSERT INTO ").append(ConfigContext.getInstance().getTableName(e.getClass())).append("(");
		Collection<Field> fieldArray=fieldMap.values();
		int i = 0, size = fieldArray.size();
		Set<String> keySet=fieldMap.keySet();
		Map beanMap=BeanUtils.mapFromBean(e);
		Object[] params=new Object[keySet.size()];
		for (String key : keySet)
		{
			sql.append(key);
			if (i < size - 1)
			{
				sql.append(",");
			}
			params[i]=beanMap.get(fieldMap.get(key).getName());
			i++;
		}
		sql.append(") VALUES (");
		for (i=0;i<size;i++)
		{
			sql.append("?");
			if (i < size - 1)
			{
				sql.append(",");
			}
		}
		sql.append(")");
		SQLRunner runner=new SQLRunner(dataSource.getConnection());
		try
		{
			runner.execute(sql.toString(),params);
		} finally
		{
			runner.closeConn();
		}
	}

	public void add(List<E> c) throws Exception
	{
		SQLRunner runner=new SQLRunner(dataSource.getConnection());
		try
		{
			E e=c.get(0);
			Map<String,Field> fieldsMap= ConfigContext.getInstance().getDataField(e.getClass());
			
			StringBuffer sql = new StringBuffer();
			sql.append("INSERT INTO ").append(ConfigContext.getInstance().getTableName(e.getClass())).append("(");
			Set<String> keySet=fieldsMap.keySet();
			int i = 0, size = keySet.size();
			for (String key : keySet)
			{
				sql.append(key);
				if (i < size - 1)
				{
					sql.append(",");
				}
				i++;
			}
			sql.append(") VALUES (");
			for (i=0;i<size;i++)
			{
				sql.append("?");
				if (i < size - 1)
				{
					sql.append(",");
				}
			}
			sql.append(")");
			Object[][] params=new Object[c.size()][keySet.size()];
			i=0;
			for(E obj:c){
				Map beanMap=BeanUtils.mapFromBean(obj);
				int j=0;
				for (String key : keySet)
				{
					params[i][j]=beanMap.get(fieldsMap.get(key).getName());
					j++;
				}
				i++;
			}
			runner.batch(sql.toString(), params);
		} finally
		{
			runner.closeConn();
		}
	}

	
	public void update(E e,String ... collname) throws Exception
	{
		Map<String,Field> fieldsMap = ConfigContext.getInstance().getDataField(e.getClass());
		StringBuffer sql = new StringBuffer();
		sql.append("UPDATE ").append(ConfigContext.getInstance().getTableName(e.getClass())).append(" SET ");
		int i = 0, size = fieldsMap.size();
		if(collname!=null&&collname.length>0){
			
		}
		Set<String> keySet=fieldsMap.keySet();
		Map beanMap=BeanUtils.mapFromBean(e);
		Object[] params=new Object[keySet.size()+1];
		for (String key : keySet)
		{
			sql.append(key).append(" = ? ");
			if (i < size - 1)
			{
				sql.append(",");
			}
			params[i]=beanMap.get(fieldsMap.get(key).getName());
			i++;
		}
		Field idfield=ConfigContext.getInstance().getIdField(e.getClass());
		sql.append(" WHERE ").append(ConfigContext.getInstance().getIdCollmun(idfield)).append("= ?");
		params[i]=beanMap.get(idfield.getName());
		
		SQLRunner runner=new SQLRunner(dataSource.getConnection());
		try
		{
			runner.execute(sql.toString(),params);
		} finally
		{
			runner.closeConn();
		}
	}

	
}
